package com.iias.communication.business;

import com.iias.common.util.arr.ZbCollectionUtils;
import com.iias.common.util.log.LogUtils;
import com.iias.communication.annotations.CICData;
import com.iias.communication.annotations.CICRequest;
import com.iias.communication.annotations.CICResponse;
import com.iias.communication.domain.InstructionInfo;
import com.iias.communication.enums.Protocol;
import com.iias.communication.packet.PacketBody;
import org.slf4j.Logger;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.LinkedList;
import java.util.List;

/**
 * 业务层逻辑处理 映射
 */
public class BusinessServiceMap {

    private final static Logger log = LogUtils.getLogger();

    private static final LinkedList<InstructionInfo> REQUEST_INFO_LIST = new LinkedList<InstructionInfo>();

    private static final LinkedList<InstructionInfo> RESPONSE_INFO_LIST = new LinkedList<InstructionInfo>();

    public static void addAll(List<BusinessSerializable> objectList){
        for (BusinessSerializable serializable : objectList) {
            add(serializable);
        }
    }


    public static void add(BusinessSerializable serializable){
        Method[] methods = serializable.getClass().getDeclaredMethods();
        if (methods != null && methods.length >0){
            for (Method method : methods) {
                Parameter[] parameters = method.getParameters();
                if (parameters ==null || parameters.length != 0  ){
                    instructionInfo(serializable, method, parameters[0].getType());
                }
                Class<?> returnType = method.getReturnType();
                if (returnType == null)continue;
                instructionInfo(null, null, returnType);
            }
        }
    }

    /**
     * 请求体
     * @param type
     * @return
     */
    private static void  instructionInfo(BusinessSerializable serializable, Method method, Class type){
        Class<? extends PacketBody> packBody = null;
        if (PacketBody.class.isAssignableFrom(type))
            packBody = (Class<? extends PacketBody>)type;
        if (packBody == null)return ;
        Annotation[] annotations = type.getAnnotations();
        for (Annotation annotation : annotations) {
            String protocol = null;
            Integer msgId =null;
            if (annotation instanceof CICData){
                 msgId = ((CICData) annotation).msgId();
                 protocol = ((CICData) annotation).Protocol();
                String remake = ((CICData) annotation).remake();
                REQUEST_INFO_LIST.add( new InstructionInfo(msgId,serializable,method,protocol,remake,packBody));
                RESPONSE_INFO_LIST.add(new InstructionInfo(msgId,serializable,method,protocol,remake,packBody));
            }else if (annotation instanceof CICResponse){
                 msgId = ((CICData) annotation).msgId();
                 protocol = ((CICData) annotation).Protocol();
                String remake = ((CICData) annotation).remake();
                RESPONSE_INFO_LIST.add(new InstructionInfo(msgId,serializable,method,protocol,remake,packBody));
            }else if (annotation instanceof CICRequest){
                 msgId = ((CICData) annotation).msgId();
                 protocol = ((CICData) annotation).Protocol();
                String remake = ((CICData) annotation).remake();
                REQUEST_INFO_LIST.add( new InstructionInfo(msgId,serializable,method,protocol,remake,packBody));
            }
            if (protocol!=null ){
                Protocol protocolN = Protocol.valueOf(protocol);
                protocolN.getDecode().addPacketBody(msgId,packBody);

            }
        }
        return ;
    }



    public static InstructionInfo getRequest(int msgId) {
        return ZbCollectionUtils.indexObj(REQUEST_INFO_LIST,msgId);
    }

    public static InstructionInfo getResponse(int msgId) {
        return ZbCollectionUtils.indexObj(RESPONSE_INFO_LIST,msgId);
    }

    public static InstructionInfo getResponse(PacketBody packetBody){
        return ZbCollectionUtils.indexObj(RESPONSE_INFO_LIST,packetBody);
    }
}
